home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
wtj007.zip
/
CURTAIN.ZIP
/
RS232.ASM
Wrap
Assembly Source File
|
1992-07-24
|
11KB
|
483 lines
*************** rs232.asm (part 3) *****************
; This code is not locked in memory. Since it is called directly &
; not at async time - its safe for it to be swapped.
VxD_CODE_SEG
BeginProc Com_API_Proc
; See if we have to convert the pointer
mov ax, [ebp.Client_AX]
cmp ax, FUNC_READ
je short cap10
cmp ax, FUNC_WRITE
je short cap10
cmp ax, FUNC_CALL_BACK
jne short cap20
; Convert it
cap10: push eax
mov ax, (Client_ES SHL 8) OR Client_DX
VMMcall Map_Flat
mov [ebp.Client_EDX], eax
pop eax
cap20: cmp ax, NUM_COM_API
jae short cap40
; If ComVm is set & this VM isn't it - return an error
cmp ComVm, ebx
jne short cap50
; Copy parameters
cap30: mov ecx, [ebp.Client_ECX]
mov edx, [ebp.Client_EDX]
movzx eax, ax
shl eax, 2
call [ComApiTabl + eax]
; Copy return values
mov [ebp.Client_EAX], eax
mov [ebp.Client_ECX], ecx
mov [ebp.Client_EDX], edx
ret
cap40: mov [ebp.Client_AX], ERROR_UNKNOWN_FUNCTION
ret
; If ComVm is 0 AND this is an open - allow it
cap50: cmp ComVm, 0
je short cap70
cap60: mov [ebp.Client_AX], ERROR_NOT_OPENED
ret
cap70: cmp ax, FUNC_OPEN
jne short cap60
jmp short cap30
EndProc Com_API_Proc
; The following are the actual functions that other apps can call.
; There are multiple ways we have to get to here but these guys do
; the actual work.
; Call to get use of the port
;
; ENTRY: EBX = VM
; EXIT: If we get it, AX == 0
; else AX == error number (! 0)
; USES: none
;
BeginProc ComOpen
; If ComVm is 0, we can take it. If not, we fail
cmp ComVm, 0
jne short co10
mov ComVm, ebx
push ebx
add ebx, ComCb
or [ebx.cdFlags], COMM_FL_OPENED
pop ebx
xor ax, ax
ret
co10: mov ax, ERROR_IN_USE
ret
EndProc ComOpen
; Call when we are done with the port
;
; ENTRY: EBX = VM
; EXIT: AX = 0
; USES: none
;
BeginProc ComClose
; Set ComVm to 0 so others can use it
mov ComVm, 0
mov ComCallFunc, 0
push ebx
add ebx, ComCb
and [ebx.cdFlags], not COMM_FL_OPENED
pop ebx
xor ax, ax
ret
EndProc ComClose
; Call to read from the port. It will read up to the
; number of bytes requested but only if the status
; bytes did not change from byte to byte.
;
; If there is a change, it will read up to and including
; the first changed one.
;
; ENTRY: ECX = Number of bytes to read
; EDX = buffer to copy to
; EXIT: If no status changes, AX = 0
; else, AX = error value
; ECX = Number of bytes actually read
; EDX = high 8 bits: byte 1 line status
; next 8 bits: byte 1 modem status
; next 8 bits: byte n line status
; low 8 bits: byte n modem status
; USES: none
;
BeginProc ComRead
mov edi, edx
push ecx
; Read the bytes - we copy it one byte at a time
; and check to see if we wrap & if we still have
; room. Because we have to check the status bytes
; one each byte - we can't do a rep movs
mov esi, pInRead
mov dx, [esi]
shl dx, 16
mov dx, [esi]
; We are done if esi == pInWrite
cr10: cmp esi, pInWrite
je short cr30
; Did the status change?
cmp [esi], dx
jne short cr50 ; status change
inc esi ; No - get it
inc esi
movsb ; Saved it
; Did we wrap?
cmp esi, offset32 InBuf + BUF_SIZE
jae short cr40
cr20: loop cr10
cr30: mov pInRead, esi ; Save new pointer
pop eax
sub eax, ecx
mov ecx, eax
xor ax, ax
ret
cr40: mov esi, offset32 InBuf
jmp short cr20
; We had a status change
cr50: lodsw
mov dx, ax
movsb
dec cx
cmp esi, offset32 InBuf + BUF_SIZE
jb short cr30
mov esi, offset32 InBuf
jmp short cr30
EndProc ComRead
; Call to write n bytes to the port
;
; ENTRY: ECX = number of bytes to write
; EDX = buffer to write from
; EXIT: if ok, AX = 0
; else AX = error
; ECX = bytes written
; USES: EAX, EDX, EDI, ESI
;
BeginProc ComWrite
mov esi, edx
push ecx
; Store the bytes - we copy it one byte at a time
; and check to see if we wrap & if we still have
; room. A rep movsd would be better but is not
; really relevant to VxDs & takes a lot more code.
mov edi, pOutWrite
mov edx, pOutRead
dec edx
cmp edx, offset32 OutBuf
jae short cw10
mov edx, offset32 OutBuf + BUF_SIZE - 1
; We are done if edi == pOutRead-1 (edx)
cw10: cmp edi, edx
je short cw30
movsb ; Saved it
; Did we wrap?
cmp edi, offset32 OutBuf + BUF_SIZE
jae short cw50
cw20: loop cw10
cw30: mov pOutWrite, edi ; Save new pointer
; How much did we write
pop eax
sub eax, ecx
push eax
; If the transmit buffer is empty - send a byte
mov dx, 3FDh
in al, dx
test al, 00100000b
jz short cw40
call TransmitBuf
cw40: pop ecx
xor ax, ax
ret
cw50: mov edi, offset32 OutBuf
jmp short cw20
EndProc ComWrite
; ComSetPort & ComQueryPort deleted - download sources to get them
; Set a call-back address to be called when receive
; gets full or transmit empty
;
; ENTRY: EDX = call-back address
; EXIT: AX = 0
; USES: none
;
BeginProc ComCallBack
mov ComCallFunc, edx
xor ax, ax
ret
EndProc ComCallBack
; Called when a VM ends - if it owns the port set the port to
; no owner. Without this, a VM could end & still stop another
; VM from getting the port.
BeginProc ComVmTerminate
cmp ComVm, ebx
jne short cvt10
mov ComVm, 0
mov ComCallFunc, 0
cvt10: clc
ret
EndProc ComVmTerminate
; Set up a reasonable set of port emulation values when
; a VM is created
BeginProc ComVmCreate
mov eax, ebx
add eax, ComCb
mov [eax.bLowBaud], 60h
mov [eax.bHiBaud], 0
mov [eax.bIir], 0
mov [eax.bLine], 00000111b
mov [eax.bModem], 00001011b
clc
ret
EndProc ComVmCreate
; If we terminate an app - we reset
BeginProc ComInt21
mov ah, [ebp.Client_AH]
cmp ah, 4Ch ; new terminate?
je short i21_10
cmp ah, 4Bh ; EXEC
je short i21_10
cmp ah, 31h ; TSR terminate?
je short i21_10
cmp ah, 00h ; old terminate?
je short i21_10
stc
ret
i21_10: mov eax, ebx
add eax, ComCb
and [eax.cdFlags], not COMM_FL_FAILED
stc
ret
EndProc ComInt21
; If we get an error - we reset
BeginProc ComInt23_24
mov eax, ebx
add eax, ComCb
and [eax.cdFlags], not COMM_FL_FAILED
stc
ret
EndProc ComInt23_24
VxD_CODE_ENDS
END
*************** dos_call.asm *****************
.386
IS_16 EQU 1
include rs232.inc
DGROUP group _DATA
public _CommRegister, _CommOpen, _CommClose, _CommRead, _CommWrite
public _CommSet, _CommQuery
_DATA segment dword use16 public 'DATA'
assume ds:DGROUP
CommCallAddr dd ?
_DATA ends
_TEXT segment dword use16 public 'CODE'
assume cs:_TEXT, ds:DGROUP
; Gets the call address for the RS-232 VxD
; Returns 0 if no VxD
_CommRegister proc
push di
push es
mov di, 0
mov es, di
mov ax, 1684h
mov bx, RS232_DEVICE_ID
int 2Fh
mov word ptr [CommCallAddr], di
mov word ptr [CommCallAddr+2], es
mov ax, es ; for return
or ax, di
pop es
pop di
ret
_CommRegister endp
_CommOpen proc
mov ax, FUNC_OPEN
call dword ptr [CommCallAddr]
ret
_CommOpen endp
_CommClose proc
mov ax, FUNC_CLOSE
call dword ptr [CommCallAddr]
ret
_CommClose endp
_CommRead proc
push es
push bp
push ax
mov bp, sp
mov dx, [bp + 8]
mov cx, [bp + 10]
push ds
pop es
pop ax
pop bp
mov ax, FUNC_READ
call dword ptr [CommCallAddr]
pop es
mov ax, cx
ret
_CommRead endp
_CommWrite proc
push es
push bp
push ax
mov bp, sp
mov dx, [bp + 8]
mov cx, [bp + 10]
push ds
pop es
pop ax
pop bp
mov ax, FUNC_WRITE
call dword ptr [CommCallAddr]
pop es
mov ax, cx
ret
_CommWrite endp
; _CommSet & _CommQuery deleted - download sources to get them
_TEXT ends
end